package com.lazason.wib4android;


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

public class ViewOnThouchListener implements OnTouchListener {

	// These matrices will be used to move and zoom image
	String tag = "ViewOnThouchListener";
	Matrix matrix = new Matrix();
	Matrix savedMatrix = new Matrix();
	float totalScale = 1; 
	public ImageView image;
	// We can be in one of these 3 states
	static final int NONE = 0;
	static final int DRAG = 1;
	static final int ZOOM = 2;
	int mode = NONE;

	// Remember some things for zooming
	PointF first = new PointF();  
	PointF start = new PointF();
	PointF mid = new PointF();
	float oldDist = 1f;
	
	int deviceWidth;
	int deviceHeight;
	int bitmapWidth;
	int bitmapHeight;
	  Bitmap bitmap;  
	  int max;
	  
	  private long beginTime,endTime;  

	public ViewOnThouchListener(ImageView image,Activity context) {
		super();
		this.image = image;
		 DisplayMetrics dm = new DisplayMetrics();     
		 context.getWindowManager().getDefaultDisplay().getMetrics(dm);    
		 
		 deviceWidth = dm.widthPixels;  
		 deviceHeight = dm.heightPixels;  
		 BitmapDrawable bd = (BitmapDrawable) image.getDrawable();
		 if(bd!=null){
		 bitmap = bd.getBitmap();
		 bitmapWidth = bitmap.getWidth();
		 bitmapHeight = bitmap.getHeight();
		 }
		 
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		this.image.setScaleType(ScaleType.MATRIX); 

		ImageView view = (ImageView) v;
		
		 if(bitmap==null){
			 BitmapDrawable bd = (BitmapDrawable) view.getDrawable();
			 if(bd==null){
				 return false;
			 }
		 bitmap = bd.getBitmap();
		 bitmapWidth = bitmap.getWidth();
		 bitmapHeight = bitmap.getHeight();
		 }
		// Log.e("view_width",
		// view.getImageMatrix()..toString()+"*"+v.getWidth());
		// Dump touch event to log
		dumpEvent(event);

		// Handle touch events here...
		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			 beginTime = System.currentTimeMillis();  
			matrix.set(view.getImageMatrix());
			//savedMatrix.set(matrix);
			start.set(event.getX(), event.getY());
			  first.set(event.getX(), event.getY());   
			// Log.d(TAG, "mode=DRAG");
			mode = DRAG;

			/*
			 * float scaleWidth=180f/320; float scaleHeight=240f/480;
			 * matrix.reset(); matrix.postScale(scaleWidth, scaleHeight);
			 */
			// Log.d(TAG, "mode=NONE");
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			oldDist = spacing(event);	//两点间距离
			// Log.d(TAG, "oldDist=" + oldDist);
			if (oldDist > 10f) {
				savedMatrix.set(matrix);
				midPoint(mid, event);
				mode = ZOOM;
				// Log.d(TAG, "mode=ZOOM");
			}
			break;
		case MotionEvent.ACTION_UP:
			 endTime = System.currentTimeMillis();  
             
             System.out.println("endTime=="+(endTime - beginTime));  
             float x = event.getX(0) - first.x;  
             float y = event.getY(0) - first.y;  
             // 多长的距离  
             float move = FloatMath.sqrt(x * x + y * y);  
               
             System.out.println("move=="+(move));  
               
             // 计算时间和移动的距离  来判断你想要的操作，经过测试90%情况能满足  
             if(endTime - beginTime<500&&move>20)  
             {  
                 //这里就是做你上一页下一页的事情了。  
                 //Toast.makeText(this, "----do something-----", 1000).show();  
             }  
             break;  
		case MotionEvent.ACTION_POINTER_UP:
			mode = NONE;
			// Log.e("view.getWidth", view.getWidth() + "");
			// Log.e("view.getHeight", view.getHeight() + "");

			break;
		case MotionEvent.ACTION_MOVE:
			//rect.width() rect.height() 代表图片原始大小
			Rect rect = view.getDrawable().getBounds();   
			 
			float[] values = new float[9];   
			matrix.getValues(values);   
			ImageState mapState = new ImageState();   
			//图片当前左边界
			mapState.left = values[2];   
			//图片当前上边界
			mapState.top = values[5];   
			//values[0] 是图片当前尺寸和原始尺寸的比
			mapState.right = mapState.left + rect.width() * values[0];   
			mapState.bottom = mapState.top + rect.height() * values[0];   
			
			Log.d(tag, "mapState.left="+mapState.left);
			Log.d(tag, "mapState.top="+mapState.top);
			Log.d(tag, "mapState.right="+mapState.right);
			Log.d(tag, "mapState.bottom="+mapState.bottom);
			Log.d(tag, "rect.width()="+rect.width());
			Log.d(tag, "rect.height()="+rect.height());
			Log.d(tag, "rect.top="+rect.top);
			Log.d(tag, "values[0]="+values[0]);
			
			
			if (mode == DRAG) {
				// ...
				//matrix.set(savedMatrix);
				//规则，1 图片不能整体在屏幕外； 
				//2 图片高度如果小于屏幕，上界和下界都不可以在屏幕外
				//3  图片宽度如果小于屏幕，左界和右界都不可以在屏幕外
				//4 图片高度如果大于屏幕，如果上界小于0，则下界应大于等于屏幕高度。上界不能大于0.
				//5 图片宽度如果大于屏幕，如果左界小于0，则右界应大于等于屏幕高度。左界不能大于0.
				float xDistance = event.getX() - start.x;
				float yDistance = event.getY() - start.y;
				if(rect.width() * values[0]<=deviceWidth){
				    if(mapState.left+xDistance<0){
						xDistance = 0-mapState.left;
					}
					if(mapState.right+xDistance>deviceWidth){
						xDistance = deviceWidth-mapState.right;
					}
				}else {
					if(mapState.left+xDistance>0){
						xDistance=0-mapState.left;
					}  
					if(mapState.right+xDistance<deviceWidth){
						xDistance = deviceWidth-mapState.right;
					}
				}
				if(rect.height()*values[0]<=deviceHeight){
					if(mapState.top+yDistance<0){
						yDistance=0-mapState.top;
					}
					if(mapState.bottom+yDistance>deviceHeight){
						yDistance =deviceHeight-mapState.bottom;
					}
				} else {
					if(mapState.top+yDistance>0){
						yDistance=0-mapState.top;
					}
					if(mapState.bottom+yDistance<deviceHeight){
						yDistance =deviceHeight-mapState.bottom;
					}
				}
				matrix.postTranslate(xDistance, yDistance);
				start.set(event.getX(), event.getY());  
			} else if (mode == ZOOM) {
				float newDist = spacing(event);	//新的两点间距离
				// Log.d(TAG, "newDist=" + newDist);
				
				if (newDist > 10f) {
					//matrix.set(savedMatrix);
					float scale = newDist / oldDist;	// 算出扩大还是缩小的比例
//					if(rect.width() * values[0]>deviceWidth||rect.height() * values[0]>deviceHeight){
//						
//					} else
						
						if((values[0]<0.25&&scale<1)||values[0]>4&&scale>1){
						scale =1;
					}
					Log.d(tag, "scale="+scale);
					//scale = Math.max(0.1f, Math.min(scale, 5.0f));
					matrix.postScale(scale, scale, mid.x, mid.y);
					//matrix.postScale(scale, scale);
				}
				 oldDist = newDist;  
			}
			break;
		}

		view.setImageMatrix(matrix);
		return true; // indicate event was handled
	}

	private void dumpEvent(MotionEvent event) {
		String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
				"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
		StringBuilder sb = new StringBuilder();
		int action = event.getAction();
		int actionCode = action & MotionEvent.ACTION_MASK;
		sb.append("event ACTION_").append(names[actionCode]);
		if (actionCode == MotionEvent.ACTION_POINTER_DOWN
				|| actionCode == MotionEvent.ACTION_POINTER_UP) {
			sb.append("(pid ").append(
					action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
			sb.append(")");
		}
		sb.append("[");
		for (int i = 0; i < event.getPointerCount(); i++) {
			sb.append("#").append(i);
			sb.append("(pid ").append(event.getPointerId(i));
			sb.append(")=").append((int) event.getX(i));
			sb.append(",").append((int) event.getY(i));
			if (i + 1 < event.getPointerCount())
				sb.append(";");
		}
		sb.append("]");
		// Log.d(TAG, sb.toString());
	}

	/** Determine the space between the first two fingers */
	private float spacing(MotionEvent event) {
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return FloatMath.sqrt(x * x + y * y);
	}

	/** Calculate the mid point of the first two fingers */
	private void midPoint(PointF point, MotionEvent event) {
		float x = event.getX(0) + event.getX(1);
		float y = event.getY(0) + event.getY(1);
		point.set(x / 2, y / 2);
	}
	
	public class ImageState {   
		  public float left;   
		  public float top;   
		  public float right;   
		  public float bottom;   
		}
}